home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / DJSRC111.ZIP / go32 / event.c < prev    next >
C/C++ Source or Header  |  1993-08-28  |  7KB  |  260 lines

  1. /**
  2.  ** EVENT.C
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #ifndef  __TURBOC__
  25. #error     Don't even try to compile it with this compiler
  26. #endif
  27.  
  28. #pragma  inline
  29.  
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <alloc.h>
  33. #include <stdio.h>
  34. #include <time.h>
  35. #include <dos.h>
  36.  
  37. #include "eventque.h"
  38.  
  39. extern int  far _ev_interss;    /* interrupt stack segment */
  40. extern int  far _ev_interds;    /* interrupt data segment */
  41. extern int  far _ev_kbintsp;    /* keyboard interrupt stack */
  42. extern int  far _ev_msintsp;    /* mouse interrupt stack */
  43. extern int  far _ev_kbinter;    /* keyboard interrupt flag */
  44. extern int  ctrl_c_flag;
  45.  
  46. extern void interrupt (* far _ev_oldkbint)(void);
  47.  
  48. extern void far          _ev_mouseint(void);
  49. extern void interrupt _ev_keybdint(void);
  50.  
  51. static void dummydraw(void) {}
  52.  
  53. static EventQueue *queue = NULL;
  54. static void (*mousedraw)(void) = dummydraw;
  55. static char *stack = NULL;
  56. static char *qsave = NULL;
  57.  
  58. static int  ms_xpos;
  59. static int  ms_ypos;
  60. static int  ms_xmickey;
  61. static int  ms_ymickey;
  62.  
  63. #ifdef FOR_GO32
  64. #ifndef  USE_AT_BIOS        /* always use AT BIOS calls for GO32 version */
  65. #define  USE_AT_BIOS
  66. #endif
  67. #else
  68. static int  first_call = 1;
  69. #endif
  70.  
  71. #define MS_ENABLE   EVENT_ENABLE(EVENT_MOUSE)
  72. #define KB_ENABLE   EVENT_ENABLE(EVENT_KEYBD)
  73.  
  74. #define KB_SSIZE    128        /* keyboard handler stack size */
  75. #define MS_SSIZE    128        /* mouse handler MINIMAL stack size */
  76.  
  77. #define IABS(x)        (((x) > 0) ? (x) : -(x))
  78.  
  79. void far _ev_mousehandler(int msk,int btn,int mx,int my)
  80. {
  81.     EventRecord *ep;
  82.     int moved = 0;
  83.     int diff;
  84.  
  85.     if((diff = mx - ms_xmickey) != 0) {
  86.         ms_xmickey += diff;
  87.         ms_xpos    += diff;
  88.         if((diff = ms_xpos / queue->evq_xspeed) != 0) {
  89.         ms_xpos %= queue->evq_xspeed;
  90.         if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  91.         diff += queue->evq_xpos;
  92.         if(diff <= queue->evq_xmin) diff = queue->evq_xmin;
  93.         if(diff >= queue->evq_xmax) diff = queue->evq_xmax;
  94.         if(diff != queue->evq_xpos) {
  95.             queue->evq_xpos  = diff;
  96.             queue->evq_moved = moved = 1;
  97.         }
  98.         }
  99.     }
  100.     if((diff = my - ms_ymickey) != 0) {
  101.         ms_ymickey += diff;
  102.         ms_ypos    += diff;
  103.         if((diff = ms_ypos / queue->evq_yspeed) != 0) {
  104.         ms_ypos %= queue->evq_yspeed;
  105.         if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  106.         diff += queue->evq_ypos;
  107.         if(diff <= queue->evq_ymin) diff = queue->evq_ymin;
  108.         if(diff >= queue->evq_ymax) diff = queue->evq_ymax;
  109.         if(diff != queue->evq_ypos) {
  110.             queue->evq_ypos  = diff;
  111.             queue->evq_moved = moved = 1;
  112.         }
  113.         }
  114.     }
  115.     if((msk & ~1) && (queue->evq_enable & MS_ENABLE)) {
  116.         disable();
  117.         ep = &queue->evq_events[queue->evq_wrptr];
  118.         if(++queue->evq_wrptr == queue->evq_maxsize)
  119.         queue->evq_wrptr = 0;
  120.         if(queue->evq_cursize < queue->evq_maxsize)
  121.         queue->evq_cursize++;
  122.         else if(++queue->evq_rdptr == queue->evq_maxsize)
  123.         queue->evq_rdptr = 0;
  124.         enable();
  125.         _AX = 0x200;
  126.         geninterrupt(0x16);
  127.         ep->evt_kbstat = _AL;
  128.         ep->evt_type   = EVENT_MOUSE;
  129.         ep->evt_mask   = msk;
  130.         ep->evt_button = btn;
  131.         ep->evt_xpos   = queue->evq_xpos;
  132.         ep->evt_ypos   = queue->evq_ypos;
  133.         ep->evt_time   = clock();
  134.     }
  135.     if(moved && queue->evq_drawmouse) (*mousedraw)();
  136. }
  137.  
  138. void far _ev_keybdhandler(void)
  139. {
  140.     EventRecord *ep;
  141.     int keycode,scancode;
  142.  
  143.     if(queue->evq_enable & KB_ENABLE) for( ; ; ) {
  144. #ifdef USE_AT_BIOS
  145.         _AX = 0x1100;
  146. #else
  147.         _AX = 0x100;
  148. #endif
  149.         geninterrupt(0x16);
  150.         asm jnz  charpresent;
  151.         return;
  152.       charpresent:
  153.         scancode = _AX;
  154.         if(scancode == 0)ctrl_c_flag = 1;
  155.         keycode  = (_AL == 0) ? _AH + 0x100 :
  156. #ifdef USE_AT_BIOS
  157.         (_AL == 0xe0) ? _AH + 0x200 :
  158. #endif
  159.         _AL;
  160.         if(queue->evq_delchar) {
  161. #ifdef USE_AT_BIOS
  162.         _AX = 0x1000;
  163. #else
  164.         _AX = 0;
  165. #endif
  166.         geninterrupt(0x16);
  167.         }
  168.         disable();
  169.         ep = &queue->evq_events[queue->evq_wrptr];
  170.         if(++queue->evq_wrptr == queue->evq_maxsize)
  171.         queue->evq_wrptr = 0;
  172.         if(queue->evq_cursize < queue->evq_maxsize)
  173.         queue->evq_cursize++;
  174.         else if(++queue->evq_rdptr == queue->evq_maxsize)
  175.         queue->evq_rdptr = 0;
  176.         enable();
  177. #ifdef USE_AT_BIOS
  178.         _AX = 0x1200;
  179. #else
  180.         _AX = 0x200;
  181. #endif
  182.         geninterrupt(0x16);
  183.         ep->evt_kbstat   = _AL;
  184.         ep->evt_keycode  = keycode;
  185.         ep->evt_scancode = scancode;
  186.         ep->evt_type     = EVENT_KEYBD;
  187.         ep->evt_time     = clock();
  188.     }
  189. }
  190.  
  191. void EventQueueDeInit(void)
  192. {
  193.     if(stack != NULL) {
  194.         _AX = 0;
  195.         geninterrupt(0x33);
  196. #ifdef FOR_GO32
  197.         _ev_kbinter = 1;
  198. #else
  199.         setvect(9,_ev_oldkbint);
  200. #endif
  201.         free(stack);
  202.         free(qsave);
  203.         stack = NULL;
  204.     }
  205. }
  206.  
  207. EventQueue *EventQueueInit(int qsize,int ms_stksize,void (*msdraw)(void))
  208. {
  209.     if(stack != NULL) EventQueueDeInit();
  210.     if(qsize < 20) qsize = 20;
  211.     if(ms_stksize < MS_SSIZE) ms_stksize = MS_SSIZE;
  212.     stack = malloc(KB_SSIZE + ms_stksize);
  213.     qsave = malloc(sizeof(EventQueue)+(sizeof(EventRecord)*(qsize-1))+4);
  214.     if((stack == NULL) || (qsave == NULL)) {
  215.         if(stack != NULL) { free(stack); stack = NULL; }
  216.         if(qsave != NULL) { free(qsave); qsave = NULL; }
  217.         return(NULL);
  218.     }
  219.     _ev_interds = FP_SEG(&ms_xpos);
  220.     _ev_interss = FP_SEG(stack);
  221.     _ev_kbintsp = FP_OFF(stack) + KB_SSIZE;
  222.     _ev_msintsp = FP_OFF(stack) + KB_SSIZE + ms_stksize;
  223.     ms_xpos = ms_xmickey = 0;
  224.     ms_ypos = ms_ymickey = 0;
  225.     queue = (EventQueue *)(((long)qsave + 3L) & ~3L);
  226.     memset(queue,0,sizeof(EventQueue));
  227.     queue->evq_maxsize   = qsize;
  228.     queue->evq_xmax         = 79;
  229.     queue->evq_ymax         = 24;
  230.     queue->evq_xspeed    = 8;
  231.     queue->evq_yspeed    = 16;
  232.     queue->evq_thresh    = 100;
  233.     queue->evq_accel     = 1;
  234.     queue->evq_delchar   = 1;
  235.     queue->evq_enable    = MS_ENABLE | KB_ENABLE;
  236.     _AX = 0;
  237.     geninterrupt(0x33);
  238.     if(_AX != 0) {
  239.         _AX = 11;
  240.         geninterrupt(0x33);
  241.         mousedraw = (msdraw != NULL) ? msdraw : dummydraw;
  242.         _ES = FP_SEG(_ev_mouseint);
  243.         _DX = FP_OFF(_ev_mouseint);
  244.         _CX = 0xff;
  245.         _AX = 0x0c;
  246.         geninterrupt(0x33);
  247.     }
  248. #ifndef FOR_GO32
  249.     _ev_oldkbint = getvect(9);
  250.     setvect(9,_ev_keybdint);
  251.     if(first_call) {
  252.         atexit(EventQueueDeInit);
  253.         first_call = 0;
  254.     }
  255. #endif
  256.     _ev_kbinter = (-1);
  257.     return(queue);
  258. }
  259.  
  260.